home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xjewel / logic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  9.4 KB  |  612 lines

  1. /*
  2. **
  3. **    X11 Jewel By David Cooper and Jose Guterman 05/92
  4. **
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9.  
  10. #include "general.h"
  11. #include "logic.h"
  12. #include "panel.h"
  13. #include "game.h"
  14.  
  15. int board[NUM_COLS][NUM_ROWS];
  16. int curr_block[BLOCK_SIZE];
  17. int next_block[BLOCK_SIZE];
  18. int background = BACKGND1;
  19. int curr_block_x, curr_block_y;
  20. BOOL moving_block = FALSE;
  21. struct rem_piece p_remov[NUM_COLS*NUM_ROWS];
  22. int index_rem;
  23.  
  24. void Redraw_Board()
  25.     {
  26.     int i, j;
  27.  
  28.     for (i=0; i<NUM_COLS; i++)
  29.         for (j=0; j<NUM_ROWS; j++)
  30.             Draw_Piece(board[i][j], i, j);
  31.  
  32.     for(i=0; i<BLOCK_SIZE; i++)
  33.         {
  34.         Draw_Piece(next_block[i], -1, i);
  35.         }
  36.     }
  37.  
  38. void Get_Random_Block(block)
  39. int *block;
  40.     {
  41.     int i;
  42.  
  43.     if ((random() % AVG_BLOCKS_BETWEEN_JEWELS) == 0) /* time for a jewel? */
  44.         {
  45.         for (i=0; i<BLOCK_SIZE; i++)
  46.             {
  47.             block[i] = WILD_PIECE;
  48.             }
  49.         }
  50.     else
  51.         {
  52.         for (i=0; i<BLOCK_SIZE; i++)
  53.             {
  54.             block[i] = (random() % NUM_REAL_PIECES);
  55.             }
  56.         }
  57.     }
  58.  
  59. int Get_New_Background(old_background)
  60. int old_background;
  61.     {
  62.     int bgnd;
  63.  
  64.     /* Random Background */
  65. /*
  66.     while ((bgnd = ((random() % NUM_BACKGND) + BACKGND1)) == old_background)
  67.         {}
  68. */
  69.  
  70.     /* Rotate Backgrounds */
  71.     bgnd = old_background+1;
  72.     if (bgnd >= BACKGND1 + NUM_BACKGND)
  73.         {
  74.         bgnd = BACKGND1;
  75.         }
  76.     
  77.     return(bgnd);
  78.     }
  79.  
  80. void Clear_Board()
  81.     {
  82.     int i, j;
  83.  
  84.     for (i=0; i<NUM_COLS; i++)
  85.         for (j=0; j<NUM_ROWS; j++)
  86.             {
  87.             board[i][j]=background;
  88.             }
  89.     }
  90.  
  91. Update_Board(piece, x, y)
  92. int piece, x, y;
  93.     {
  94.     board[x][y] = piece;
  95.     Draw_Piece(piece, x, y);
  96.     }
  97.  
  98. void Init_Logic()
  99.     {
  100.     /* Initialize the board to be empty */
  101.     background = Get_New_Background(BACKGND1);
  102.     Clear_Board();
  103.  
  104.     /* Prepare for the firs block */
  105.     Get_Random_Block(next_block);
  106.     moving_block = FALSE;
  107.     curr_block_x = NUM_COLS/2;
  108.     curr_block_y = 0;
  109.     }
  110.  
  111. void Clear_Remove_List()
  112.     {
  113.     index_rem = 0;
  114.     }
  115.  
  116. void Add_To_Remove_List(x, y, piece)
  117. int piece, x, y;
  118.     {
  119.     p_remov[index_rem].x = x;
  120.     p_remov[index_rem].y = y;
  121.     p_remov[index_rem].piece = piece;
  122.     index_rem++;
  123.     }
  124.  
  125. void Handle_Horiz_Line(i, j, in_line)
  126. int i, j, in_line;
  127.     {
  128.     int k;
  129.  
  130.     for (k=0; k<in_line; k++)
  131.         {
  132.         Add_To_Remove_List(j-k-1, i, board[j-1][i]);
  133.         }
  134.     }
  135.  
  136. void Handle_Vert_Line(i, j, in_line)
  137. int i, j, in_line;
  138.     {
  139.     int k;
  140.  
  141.     for (k=0; k<in_line; k++)
  142.         {
  143.         Add_To_Remove_List(i, j-k-1, board[i][j-1]);
  144.         }
  145.     }
  146.  
  147.  
  148. void Handle_DiagR_Line(i, j, in_line)
  149. int i, j, in_line;
  150.     {
  151.     int k;
  152.  
  153.     for (k=0; k<in_line; k++)
  154.         {
  155.         Add_To_Remove_List(j-k-1, i-k-1, board[j-k-1][i-k-1]);
  156.         }
  157.     }
  158.  
  159.  
  160. void Handle_DiagL_Line(i, j, in_line)
  161. int i, j, in_line;
  162.     {
  163.     int k;
  164.  
  165.     for (k=0; k<in_line; k++)
  166.         {
  167.         Add_To_Remove_List(j+k+1, i-k-1, board[j+k+1][i-k-1]);
  168.         }
  169.     }
  170.  
  171. int Check_Board()
  172.     {
  173.     int add_score;
  174.     int i, j, k, l;
  175.     int in_line;
  176.     int piece_checked;
  177.  
  178.     add_score = 0;
  179.     Clear_Remove_List();
  180.  
  181.     /* Check Horizontal */
  182.     for (i=0; i<NUM_ROWS; i++)
  183.         {
  184.         in_line = 1;
  185.         piece_checked = background;
  186.         for (j=0; j<NUM_COLS; j++)
  187.             {
  188.             if (TEST_PIECE(board[j][i]) && (board[j][i] == piece_checked))
  189.                 {
  190.                 in_line++;
  191.                 }
  192.             else
  193.                 {
  194.                 piece_checked = board[j][i];
  195.                 if (in_line > 2)
  196.                     {
  197.                     add_score = add_score + POINTS(in_line);
  198.                     Handle_Horiz_Line(i,j,in_line);
  199.                     }
  200.                 in_line = 1;
  201.                 }
  202.             }
  203.  
  204.         if (in_line > 2)
  205.             {
  206.             add_score = add_score + POINTS(in_line);
  207.             Handle_Horiz_Line(i,j,in_line);
  208.             }
  209.         }
  210.  
  211.     /* Check Vertical */
  212.     for (i=0; i<NUM_COLS; i++)
  213.         {
  214.         in_line=1;
  215.         piece_checked=background;
  216.         for (j=0; j<NUM_ROWS; j++)
  217.             {
  218.             if (TEST_PIECE(board[i][j]) && (board[i][j] == piece_checked))
  219.                 {
  220.                 in_line++;
  221.                 }
  222.             else
  223.                 {
  224.                 piece_checked = board[i][j];
  225.                 if (in_line > 2)
  226.                     {
  227.                     add_score = add_score + POINTS(in_line);
  228.                     Handle_Vert_Line(i,j,in_line);
  229.                     }
  230.                 in_line = 1;
  231.                 }
  232.             }
  233.  
  234.         if (in_line > 2)
  235.             {
  236.             add_score = add_score + POINTS(in_line);
  237.             Handle_Vert_Line(i,j,in_line);
  238.             }
  239.         }
  240.  
  241.     /* Check Diagonal Right */
  242.     k=NUM_COLS-2;
  243.     l=0;
  244.     while (l<(NUM_ROWS-2))
  245.         {
  246.         i=l;
  247.         j=k;
  248.         in_line=1;
  249.         piece_checked=background;
  250.         while((i<NUM_ROWS) && (j<NUM_COLS))
  251.             {
  252.             if (TEST_PIECE(board[j][i]) && (board[j][i] == piece_checked))
  253.                 {
  254.                 in_line++;
  255.                 }
  256.             else
  257.                 {
  258.                 piece_checked = board[j][i];
  259.                 if (in_line > 2)
  260.                     {
  261.                     add_score = add_score + POINTS(in_line);
  262.                     Handle_DiagR_Line(i,j,in_line);
  263.                     }
  264.                 in_line = 1;
  265.                 }
  266.             i++;
  267.             j++;
  268.             }
  269.  
  270.         if (in_line > 2)
  271.             {
  272.             add_score = add_score + POINTS(in_line);
  273.             Handle_DiagR_Line(i,j,in_line);
  274.             }
  275.  
  276.         if (k>0)
  277.             {
  278.             k--;
  279.             }
  280.         else
  281.             {
  282.             l++;
  283.             }
  284.         }
  285.  
  286.     /* Check Diagonal Left */
  287.     k=3;
  288.     l=0;
  289.     while (l<(NUM_ROWS-2))
  290.         {
  291.         i=l;
  292.         j=k;
  293.         in_line=1;
  294.         piece_checked=background;
  295.         while((i<NUM_ROWS) && (j>=0))
  296.             {
  297.             if (TEST_PIECE(board[j][i]) && (board[j][i] == piece_checked))
  298.                 {
  299.                 in_line++;
  300.                 }
  301.             else
  302.                 {
  303.                 piece_checked = board[j][i];
  304.                 if (in_line > 2)
  305.                     {
  306.                     add_score = add_score + POINTS(in_line);
  307.                     Handle_DiagL_Line(i,j,in_line);
  308.                     }
  309.                 in_line = 1;
  310.                 }
  311.             i++;
  312.             j--;
  313.             }
  314.  
  315.         if (in_line > 2)
  316.             {
  317.             add_score = add_score + POINTS(in_line);
  318.             Handle_DiagL_Line(i,j,in_line);
  319.             }
  320.  
  321.         if (k<(NUM_COLS-1))
  322.             {
  323.             k++;
  324.             }
  325.         else
  326.             {
  327.             l++;
  328.             }
  329.         }
  330.  
  331.     return(add_score);
  332.     }
  333.  
  334. int Remove_Flash()
  335.     {
  336.     int index;
  337.  
  338.     for (index=0; index<index_rem; index++)
  339.         {
  340.         if (board[p_remov[index].x][p_remov[index].y] == FLASH1)
  341.             {
  342.             p_remov[index].x = p_remov[index_rem-1].x;
  343.             p_remov[index].y = p_remov[index_rem-1].y;
  344.             p_remov[index].piece = p_remov[index_rem-1].piece;
  345.             index_rem--;
  346.             index--;
  347.             }
  348.         else
  349.             {
  350.             board[p_remov[index].x][p_remov[index].y] = FLASH1;
  351.             }
  352.         }
  353.  
  354.     Flash_Pieces(p_remov, index_rem, background);
  355.     }
  356.  
  357. void Drop_Down_After_Flash()
  358.     {
  359.     int i, j, k;
  360.  
  361.     for (i=0; i<NUM_COLS; i++)
  362.         for (j=0; j<NUM_ROWS; j++)
  363.             {
  364.             if (board[i][j] == FLASH1)
  365.                 {
  366.                 for (k=j-1; k>=0; k--)
  367.                     {
  368.                     Update_Board(board[i][k], i, k+1);
  369.                     }
  370.                 Update_Board(background, i, 0);
  371.                 }
  372.             }
  373.     }
  374.  
  375. void Redraw_Background()
  376.     {
  377.     int i, j;
  378.  
  379.     for (i=0; i<NUM_COLS; i++)
  380.         for (j=0; j<NUM_ROWS; j++)
  381.             if (!TEST_PIECE(board[i][j])) 
  382.                 {
  383.                 Update_Board(background, i, j);
  384.                 }
  385.     }
  386.  
  387. void Update_Rest(num_pieces)
  388. int num_pieces;
  389.     {
  390.     if (Dec_Rest(num_pieces))
  391.         {
  392.         background = Get_New_Background(background);
  393.         Redraw_Background();
  394.         }
  395.     }
  396.  
  397. void Process_Block(special, piece)
  398. BOOL special;
  399. int piece;
  400.     {
  401.     int i, j;
  402.     int add_score;
  403.     
  404.     if (special)
  405.         {
  406.         Clear_Remove_List();
  407.         for (i=0; i<NUM_COLS; i++)
  408.             for (j=0; j<NUM_ROWS; j++)
  409.                 if ((board[i][j] == WILD_PIECE) ||
  410.                     ((board[i][j] == piece) && TEST_PIECE(board[i][j])))
  411.                     {
  412.                     Add_To_Remove_List(i, j, board[i][j]);
  413.                     }
  414.  
  415.         Remove_Flash();
  416.         Drop_Down_After_Flash();
  417.         Add_Score(JEWELSCORE, 1);
  418.         Update_Rest(index_rem);
  419.         }
  420.  
  421.     i = 1;
  422.     while ((add_score = Check_Board()) > 0)
  423.         {
  424.         Remove_Flash();
  425.         Drop_Down_After_Flash();
  426.         Add_Score(add_score, i);
  427.         Update_Rest(index_rem);
  428.         i++;
  429.         }
  430.  
  431.     if (TEST_PIECE(board[NUM_COLS/2][BLOCK_SIZE-1]))
  432.         {
  433.         Melt_Down();
  434.         Clear_Board();
  435.         Redraw_Board();
  436.         Dec_Lives();
  437.         }
  438.     }
  439.  
  440. void Move_Right()
  441.     {
  442.     int i;
  443.  
  444.     if (!moving_block) 
  445.         {
  446.         return;
  447.         }
  448.  
  449.     if (curr_block_x < (NUM_COLS-1))
  450.         {
  451.         for (i=0; i<BLOCK_SIZE; i++)
  452.             {
  453.             if (TEST_PIECE(board[curr_block_x+1][curr_block_y+i]))
  454.                 {
  455.                 return;
  456.                 }
  457.             }
  458.  
  459.         curr_block_x++;
  460.         for (i=0; i<BLOCK_SIZE; i++)
  461.             {
  462.             Update_Board(curr_block[i], curr_block_x, curr_block_y+i);
  463.             Update_Board(background, curr_block_x-1, curr_block_y+i);
  464.             }
  465.  
  466.         Key_Bell();
  467.         }
  468.     }
  469.  
  470. void Move_Left()
  471.     {
  472.     int i;
  473.     if (!moving_block)
  474.         {
  475.         return;
  476.         }
  477.  
  478.     if (curr_block_x > 0)
  479.         {
  480.         for (i=0; i<BLOCK_SIZE; i++)
  481.             {
  482.             if (TEST_PIECE(board[curr_block_x-1][curr_block_y+i]))
  483.                 {
  484.                 return;
  485.                 }
  486.             }
  487.  
  488.         curr_block_x--;
  489.         for (i=0; i<BLOCK_SIZE; i++)
  490.             {
  491.             Update_Board(curr_block[i], curr_block_x, curr_block_y+i);
  492.             Update_Board(background, curr_block_x+1, curr_block_y+i);
  493.             }
  494.  
  495.         Key_Bell();
  496.         }
  497.     }
  498.  
  499. void Move_Down()
  500.     {
  501.     int i;
  502.  
  503.     if ((curr_block_y == (NUM_ROWS - BLOCK_SIZE)) ||
  504.         (TEST_PIECE(board[curr_block_x][curr_block_y+BLOCK_SIZE])))
  505.         {
  506.         moving_block = FALSE;
  507.         if (curr_block[0] == WILD_PIECE)
  508.             {
  509.             if (curr_block_y == NUM_ROWS-BLOCK_SIZE)
  510.                 {
  511.                 Process_Block(TRUE, background);
  512.                 }
  513.             else
  514.                 {
  515.                 Process_Block(TRUE,
  516.                     board[curr_block_x][curr_block_y+BLOCK_SIZE]);
  517.                 }
  518.             }
  519.         else
  520.             {
  521.             Process_Block(FALSE, NULL);
  522.             }
  523.         }
  524.     else
  525.         {
  526.         for (i=0; i<BLOCK_SIZE; i++)
  527.             {
  528.             Update_Board(curr_block[i], curr_block_x, curr_block_y+i+1);
  529.             }
  530.         Update_Board(background, curr_block_x, curr_block_y);
  531.         curr_block_y++;
  532.         }
  533.     }
  534.  
  535. void Drop()
  536.     {
  537.     int cycles=(-1);
  538.     int i,j;
  539.     if (!moving_block)
  540.         {
  541.         return;
  542.         }
  543.  
  544.     Key_Bell();
  545.     /* we have to find the number of steps it falls here
  546.        so we can show the points first */
  547.     i=curr_block_x;
  548.     j=curr_block_y+BLOCK_SIZE;
  549.  
  550.     while (j<NUM_ROWS)
  551.         {
  552.         if (TEST_PIECE(board[i][j]))
  553.             {
  554.             break;
  555.             }
  556.         cycles++;
  557.         j++;
  558.         }
  559.     if (cycles>0)
  560.         {
  561.         Add_Raw_Score(DROP_POINTS, cycles);
  562.         }
  563.  
  564.     while(moving_block)
  565.         {
  566.         Move_Down();
  567.         }
  568.     }
  569.  
  570. void Rotate()
  571.     {
  572.     int i;
  573.     int tmp_block=curr_block[BLOCK_SIZE-1];
  574.     if (!moving_block) return;
  575.     for (i=BLOCK_SIZE-1; i>0; i--)
  576.         {
  577.         curr_block[i]=curr_block[i-1];
  578.         Update_Board(curr_block[i], curr_block_x, curr_block_y+i);
  579.         }
  580.     curr_block[0]=tmp_block;
  581.     Update_Board(curr_block[0], curr_block_x, curr_block_y);
  582.     Key_Bell();
  583.     }
  584.  
  585. void Logic_Timeout()
  586.     {
  587.     int i;
  588.  
  589.     if (!moving_block)
  590.         {
  591.         curr_block_x = NUM_COLS/2;
  592.         curr_block_y = 0;
  593.  
  594.         for (i=0; i<BLOCK_SIZE; i++)
  595.             {
  596.             curr_block[i] = next_block[i];
  597.             Update_Board(curr_block[i], curr_block_x, curr_block_y+i);
  598.             }
  599.  
  600.         Get_Random_Block(next_block);
  601.         for(i=0; i<BLOCK_SIZE; i++)
  602.             {
  603.             Draw_Piece(next_block[i], -1, i);
  604.             }
  605.         moving_block = TRUE;
  606.         }
  607.     else
  608.         {
  609.         Move_Down();
  610.         }
  611.     }
  612.